/**
 * @file uart.h
 * @brief T1 UART Controller
 *
 * @author yemt@witsi.cn
 * @date 2011-08-04
 * @version T1.UART.01
 */
#ifndef T1_UART_H_
#define T1_UART_H_

#include "iodef.h"

typedef struct {
        __IO uint32_t TDR;      /*< UART Transmit Data Register     */
        __IO uint32_t RDR;      /*< UART Receive Data Register      */
        __IO uint32_t CSR;      /*< UART Current Status Register    */
        __IO uint32_t ISR;      /*< UART Interrupt Status Register  */
        __IO uint32_t IER;      /*< UART Interrupt Enable Register  */
        __IO uint32_t ICR;      /*< UART Interrupt Clear Register   */
        __IO uint32_t GCR;      /*< UART Global Control Register    */
        __IO uint32_t CCR;      /*< UART Common Control Register    */
        __IO uint32_t BRR;      /*< UART Baud Rate Register         */
}uart_reg_t;

/* CSR */
#define UART_CSR_TX_FIFO_EPT     _BIT(3)        /*< TX FIFO is empty */
#define UART_CSR_TX_FULL         _BIT(2)        /*< TX FIFO is full */
#define UART_CSR_RX_AVL          _BIT(1)        /*< RX FIFO has a complete available byte data */
#define UART_CSR_TX_EPT          _BIT(0)        /*< TX FIFO and TX shift register are empty */

/* ISR, IER, ICR */
#define UART_INT_RX_BRK          _BIT(6)        /*< Detect a break condition */
#define UART_INT_RX_FERR         _BIT(5)        /*< Detect a frame error */
#define UART_INT_RX_PERR         _BIT(4)        /*< Detect a parity error */
#define UART_INT_RX_OERR         _BIT(3)        /*< Detect a overrun error */
#define UART_INT_TIMEOUT         _BIT(2)
#define UART_INT_RX_AVL          _BIT(1)        /*< RX FIFO has available byte data */
#define UART_INT_TX_AVL          _BIT(0)        /*< TX FIFO empty */

/* GCR */
#define UART_TX_EN           _BIT(10)            /*< Transmitter enabled */
#define UART_TX_TRIG_N_MSK   _MASK(8, 2)         /*< Transmitter FIFO trigger level */
#define UART_TX_TRIG_N(n)    _VALUE(8, (n))
#define UART_RX_EN           _BIT(6)             /*< Receiver Enable */
#define UART_RX_TRIG_N_MSK   _MASK(4, 2)         /*< Receiver FIFO trigger level  */
#define UART_RX_TRIG_N(n)    _VALUE(4, (n))
#define UART_AF_EN           _BIT(2)             /*< Auto Flow Control Enable */
#define UART_EN              _BIT(0)             /*< UART module enable */

/* CCR */
#define UART_CHAR_MSK        _MASK(4, 2)
#define UART_CHAR(n)         _VALUE(4, (n))
#define UART_BRK_EN          _BIT(3)
#define UART_STOP_BIT_2      _BIT(2)
#define UART_PARITY_EVEN     _BIT(1)
#define UART_PARITY_EN       _BIT(0)

#define UART1   ((uart_reg_t *)T1_UART1_BASE)
#define UART2   ((uart_reg_t *)T1_UART2_BASE)
#define UART3   ((uart_reg_t *)T1_UART3_BASE)

typedef struct {
        union {
                __IO uint32_t RBR; /*< Receive Buffer Register */
                __IO uint32_t THR; /*< Transmit Holding Register */
                __IO uint32_t DLL; /*< Divisor Latch (Low) */
        };
        union {
                __IO uint32_t DLH; /*< Divisor Latch (High) */
                __IO uint32_t IER; /*< Interrupt Enable Register */
        };
        union {
                __IO uint32_t IIR; /*< Interrupt Identification Register */
                __IO uint32_t FCR; /*< FIFO Control Register */
        };
        __IO uint32_t LCR; /*< Line Control Register */
        __IO uint32_t MCR; /*< Modem Control Register */
        __IO uint32_t LSR; /*< Line Status Register */
        __IO uint32_t MSR; /*< Modem Status Register */
        __IO uint32_t SCR; /*< Scratchpad Register */
        __IO uint32_t LPDLL; /*< Low Power Divisor Latch (Low) Register */
        __IO uint32_t LPDLH; /*< Low Power Divisor Latch (High) Register */
        __IO uint32_t Reserved1[(0x7c-0x28)/4];
        __IO uint32_t USR; /*< UART Status Register */
        __IO uint32_t TFL; /*< Transmit FIFO Level */
        __IO uint32_t RFL; /*< Receive FIFO Level */
}uart0_reg_t;

#define UARTA_IER_INT_EN								_BIT(7) /* enable the generation of THRE Interrupt */
#define UARTA_IER_MODEM_STATUS_INT_EN  					_BIT(3) /* Enable Modem Status Interrupt */
#define UARTA_IER_REC_LINE_STA_INT_EN 					_BIT(2) /* Enable Receiver Line Status Interrupt */
#define UARTA_IER_TRANS_HOLD_EM_INT_EN 					_BIT(1) /* Enable Transmit Holding Register Empty Interrupt */
#define UARTA_IER_REC_DATA_INTN_EN 						_BIT(0) /* Enable Received Data Available Interrupt */


#define UARTA_IIR_MODEM_INT_STATUS                   	(0)/*  */
#define UARTA_IIR_NO_INT_PENDING						_VALUE(0,0x01) /* no interrupt pending */
#define UARTA_IIR_THR_EMPTY								_VALUE(0,0x02) /* THR empty */
#define UARTA_IIR_REC_DATA_AVAILABLE					_VALUE(0,0x04) /* received data available */
#define UARTA_IIR_REC_LINE_AVAILABLE					_VALUE(0,0x06) /* receiver line status */
#define UARTA_IIR_BUSY_DETECT							_VALUE(0,0x07) /* busy detect */
#define UARTA_IIR_CHARACTER_TIMEOUT						_VALUE(0,0x0C) /* character timeout  */
#define UARTA_IIR_FIFO_EN								_VALUE(6,3) /* FIFOs Enabled */

#define UARTA_FCR_RCVR_ONE_IN_FIFO						_VALUE(6,0x0) /* 1 character in the FIFO */
#define UARTA_FCR_RCVR_QUARTER_IN_FIFO					_VALUE(6,0x1) /* FIFO 1/4 full */
#define UARTA_FCR_RCVR_HALF_IN_FIFO						_VALUE(6,0x2) /* FIFO 1/2 fulL */
#define UARTA_FCR_RCVR_LESS_TWO_IN_FIFO					_VALUE(6,0x3) /* FIFO 2 less than full  */
#define UARTA_FCR_TET_EMPTY								_VALUE(4,0x0) /* FIFO empty  */
#define UARTA_FCR_TET_TWO_IN_FIFO						_VALUE(4,0x1) /* 2 characters in the FIFO  */
#define UARTA_FCR_TET_QUARTER_IN_FIFO					_VALUE(4,0x2) /* IFO 1/4 full */
#define UARTA_FCR_TET_HALF_IN_FIFO						_VALUE(4,0x3) /* FIFO 1/2 fulL */
#define UARTA_FCR_DMAM									_BIT(3) /* DMA mode: mode 1 */
#define UARTA_FCR_XFIFOR								_BIT(2) /* XMIT FIFO Reset */
#define UARTA_FCR_RFIFOR								_BIT(1) /* RCVR FIFO Reset */
#define UARTA_FCR_FIFOE									_BIT(0) /* FIFO Enable */

#define UARTA_LCR_DLA_EN								_BIT(7) /* enable reading and writing of the Divisor Latch register */
#define UARTA_LCR_BREAK_CTL								_BIT(6) /* forced  the serial output to the spacing (logic 0) state */
#define UARTA_LCR_EPS_EN								_BIT(4) /* set to one, an even number of logic 1s is transmitted or checked */
#define UARTA_LCR_PEN									_BIT(3) /* Parity Enable */
#define UARTA_LCR_STOP									_BIT(2) /* 1.5 stop bits when DLS (LCR[1:0]) is zero, else 2 stop bit  */
#define UARTA_LCR_WLS_5									_VALUE(0,0) /*  5 bits */
#define UARTA_LCR_WLS_6									_VALUE(0,1) /*  6 bits */
#define UARTA_LCR_WLS_7									_VALUE(0,2) /*  7 bits */
#define UARTA_LCR_WLS_8									_VALUE(0,3) /*  8 bits */

#define UARTA_MCR_SIRE									_BIT(6) /* IrDA SIR Mode enabled */
#define UARTA_MCR_AFCE									_BIT(5) /* Auto Flow Control Mode enabled */
#define UARTA_MCR_LoopBack								_BIT(4) /* This is used to put the UART into a diagnostic mode for test purposes */
#define UARTA_MCR_OUT2									_BIT(3) /* out2_n asserted (logic 0)  */
#define UARTA_MCR_OUT1									_BIT(2) /* out1_n asserted (logic 0) */
#define UARTA_MCR_RTS									_BIT(1) /* Request to Send */
#define UARTA_MCR_DTR									_BIT(0) /* Data Terminal Ready*/

#define UARTA_LSR_RFE_ERROR_IN_RX_FIFO					_BIT(7) /* error in RX FIFO */
#define UARTA_LSR_TEMT									_BIT(6) /* this bit is set whenever the Transmitter Shift Register and the FIFO are both empty */
#define UARTA_LSR_THRE									_BIT(5) /* whenever data is transferred from the THR or TX FIFO to the transmitter shift register and no new data has been written to the THR or TX FIFO This also causes a
THRE Interrupt to occur */
#define UARTA_LSR_BI									_BIT(4) /* Break Interrupt bit */
#define UARTA_LSR_FE_FRAMING_ERR						_BIT(3) /* framing error  */
#define UARTA_LSR_PE_PARITY_ERR							_BIT(2) /* parity error  */
#define UARTA_LSR_OE_OVER_ERR							_BIT(1) /* overrun error */
#define UARTA_LSR_DR_DATA_READ							_BIT(0) /* data ready */

#define UARTA_MSR_DCD_LOGIC_0							_BIT(7) /* dcd_n input is asserted (logic 0)  */
#define UARTA_MSR_RI									_BIT(6) /* ri_n input is asserted (logic 0)  */
#define UARTA_MSR_DSR									_BIT(5) /* dsr_n input is asserted (logic 0) */
#define UARTA_MSR_CTS									_BIT(4) /* cts_n input is asserted (logic 0)  */
#define UARTA_MSR_DDCD									_BIT(3) /* change on dcd_n since last read of MSR */
#define UARTA_MSR_TERI									_BIT(2) /* change on ri_n since last read of MSR  */
#define UARTA_MSR_DDSR									_BIT(1) /* change on dsr_n since last read of MSR */
#define UARTA_MSR_DCTS									_BIT(0) /* change on ctsdsr_n since last read of MSR */

#define UARTA_USR_RFE_FIFO_FULL							_BIT(4) /* Receive FIFO Full */
#define UARTA_USR_RFNE_FIFO_NOT_EMPTY					_BIT(3) /* Receive FIFO is not empty */
#define UARTA_USR_TFE_FIFO_EMPTY						_BIT(2) /* Transmit FIFO is empty */
#define UARTA_USR_TRAN_FIFO_NOT_FULL					_BIT(1) /* Transmit FIFO is not full  */
#define UARTA_USR_BUSY									_BIT(0) /* DW_apb_uart is busy (actively transferring data)  */

#endif /* T1_UART_H_ */
